package di

import (
	"wire/internal/config"
	"wire/internal/database"
	"wire/internal/server"
	"wire/internal/user"

	"github.com/gin-gonic/gin"
	"github.com/google/wire"
)

// 定义 Provider Set
// 基础设施层
var InfrastructureSet = wire.NewSet(
	config.Load,
	database.NewDB,
)

// Repository 层
var RepositorySet = wire.NewSet(
	user.NewRepository,
	wire.Bind(new(user.Repository), new(*user.repository)),
)

// service 层
var ServiceSet = wire.NewSet(
	user.NewService,
	wire.Bind(new(user.Service), new(*user.service)),
)

// handler层
var HandlerSet = wire.NewSet(
	user.NewHandler,
)

// Server层
var ServerSet = wire.NewSet(
	server.NewServer,
)

// App结构体，包含所有依赖
type App struct {
	Server *server.Server
	DB     *database.DB
}

// 从配置中提取数据库连接字符串
func provideDBFromConfig(cfg *config.Config) string {
	return cfg.Database.DSN
}

// 从配置中提取端口
func providePortRegistration(cfg *config.Config) string {
	return cfg.Server.Port
}

// 注册路由的函数
func provideRouteRegistration(userHandler *user.Handler) func(*gin.Engine) {
	return func(router *gin.Engine) {
		userHandler.RegisterRoutes(router)
	}
}

// 初始化应用-wire的入口函数
func InitializeApp() (*App, error) {
	wire.Build(
		//组合所有 provider set
		InfrastructureSet,
		RepositorySet,
		ServiceSet,
		HandlerSet,
		ServerSet,

		// 提供数据库连接字符串
		provideDBFromConfig,

		// 提供服务器端口
		providePortRegistration,

		// 注册路由
		provideRouteRegistration,

		// 创建最终的 App 结构
		wire.Struct(new(App), "*"),
	)
	return &App{}, nil
}
